from celery import Celery
from dateutil import parser
from urllib.parse import quote

from api.cginstance.apis import CgInstanceApis
from api.metabase.apis import MetabaseApi
from utils.sqlalchemy.medel import FlowReport, VmCheck
from utils.sqlalchemy.sqlalchemy_manager import DatabaseManager
from utils.vm_check.vm_check import NetworkInspector

from config.config import DB_URL, CELERY_BROKER_URL

db_manager = DatabaseManager(DB_URL)

cel = Celery('yanfeng', broker=CELERY_BROKER_URL)

cel.conf.broker_connection_retry_on_startup = True
# 配置手动确认机制
cel.conf.task_acks_late = True


# cel.conf.update(1
#     worker_pool='threads',
#     worker_concurrency=10,
#     worker_loglevel='INFO'
# )
def cover(data):
    data['date'] = parser.parse(data['date'])
    return data


NetworkInspectorExe = NetworkInspector()


@cel.task(bind=True)
def get_flow_id_by_vmid(self, biz_id, biz_name, vmids):
    try:
        dynamics_filter = ["=", ["field-id", 8575]]
        for vmid in vmids:
            vmid = str(vmid)
            dynamics_filter.append(vmid)
        data = {"database": 134, "query": {"source-table": 744, "filter": ["and",
                                                                           ["time-interval", ["field-id", 8577], -4,
                                                                            "hour",
                                                                            {"include-current": True}],
                                                                           ["=", ["field-id", 8589, None], "4103"],
                                                                           ["=", ["field-id", 8617, None], "0"],
                                                                           ["=", ["field-id", 8609, None], str(biz_id)],
                                                                           dynamics_filter
                                                                           ],
                                           "aggregation": [["count"]], "breakout": [["field-id", 8612, None]]},
                "type": "query",
                "parameters": []}
        resp = MetabaseApi.dataset(data)
        rows = resp.get('data').get('rows')
        if not rows:
            return
        flowids_filter = list(filter(lambda x: x[0].split("_")[0] == "4103", rows))
        flowids = set(map(lambda x: x[0], flowids_filter))
        batch_data = []
        for flowid in flowids:
            single_data = {
                "biz_id": biz_id,
                "biz_name": biz_name,
                "flow_id": flowid
            }
            batch_data.append(single_data)
        db_manager.insert_data(FlowReport, batch_data)
    except Exception as e:
        self.retry(exc=e, countdown=10, max_retries=3)


@cel.task(bind=True)
def query_dataset(self, flow_ids):
    try:
        filter_flow_ids = [
            "=",
            [
                "field",
                8612,
                None
            ]
        ]
        filter_flow_ids.extend(flow_ids)
        data = {
            "database": 134,
            "parameters": [
            ],
            "query": {
                "aggregation": [
                    [
                        "count"
                    ]
                ],
                "breakout": [
                    [
                        "field",
                        8612,
                        None
                    ]
                ],
                "filter": [
                    "and",
                    [
                        "time-interval",
                        [
                            "field",
                            8618,
                            None
                        ],
                        0,
                        "day",
                        {
                            "include-current": None
                        }
                    ],
                    # [
                    #     "=",
                    #     [
                    #         "field",
                    #         8609,
                    #         None
                    #     ],
                    #     str(biz_id)
                    # ],
                    [
                        "=",
                        [
                            "field",
                            8566,
                            None
                        ],
                        1
                    ],
                    filter_flow_ids
                ],
                "source-table": 744
            },
            "type": "query"
        }
        resp = MetabaseApi.dataset(data)
        rows = resp.get('data').get('rows')
        fail_flow_id_list = list(map(lambda x: x[0], rows))
        success_flow_id_list = list(set(flow_ids) - set(fail_flow_id_list))
        print(f"正常的流水{len(success_flow_id_list)}个 异常的流程{len(fail_flow_id_list)}个")
        db_manager.update_data(FlowReport, update_data={"status": 1}, in_filters={"flow_id": success_flow_id_list})
        db_manager.update_data(FlowReport, update_data={"status": 2}, in_filters={"flow_id": fail_flow_id_list})
    except Exception as e:
        self.retry(exc=e, countdown=10, max_retries=3)


def insert_error_data(db_manager, VmCheck, biz_id, biz_name, vmid, error_type):
    data = {
        "biz_id": biz_id,
        "biz_name": biz_name,
        "vmid": vmid,
        "error_type": error_type,
    }
    db_manager.insert_data(VmCheck, data)


@cel.task(bind=True, queue='hand_not_available_vm')
def hand_not_available_vm(self, biz_id, biz_name, vmid, ip):
    is_vnc = NetworkInspectorExe.check_vnc_connection(ip=ip)
    if not is_vnc:
        insert_error_data(db_manager, VmCheck, biz_id, biz_name, vmid, 1)
        return
    is_cginstance = NetworkInspectorExe.check_cginstanceagent_api(ip=ip)
    if not is_cginstance:
        insert_error_data(db_manager, VmCheck, biz_id, biz_name, vmid, 2)
        return
    is_service = NetworkInspectorExe.check_cgvmagent_api(ip=ip)
    if not is_service:
        insert_error_data(db_manager, VmCheck, biz_id, biz_name, vmid, 3)
        return
